<?php

namespace common\service;


use think\Cache;
use support\SingletonTrait;
use common\service\project_warning_rules\EpisodeModifyTimeCheck;
use common\service\project_warning_rules\EpisodeSealNumberCheck;
use common\service\project_warning_rules\EpisodeAssetShotNumberCheck;
use common\service\project_warning_rules\ProjectWarningRuleInterface;
use common\service\project_warning_rules\EpisodeSealDateTaskProgressCheck;

/**
 * 项目风险预警
 */
class ProjectWarningService
{
    use SingletonTrait;

    /** @var ProjectWarningRuleInterface[] */
    protected $registeredProjectWarningRules = [];

    public function __construct()
    {
        $this->registeredProjectWarningRules = [
            EpisodeSealNumberCheck::getInstance(),
            EpisodeSealDateTaskProgressCheck::getInstance(),
            EpisodeModifyTimeCheck::getInstance(),
            EpisodeAssetShotNumberCheck::getInstance(),
        ];
    }

    /**
     * 查询扣分值
     * @return int
     */
    public function getProjectRuleSubScore()
    {
        return intval(OptionsService::getInstance()->getOptionsConfigItemData('project_warning_check', 'rule_score', 1));
    }

    /**
     * 查询项目风险分数和错误信息
     * @param $projectId
     * @param int $cached
     * @return array
     */
    public function getScoreAndErrorMessage($projectId, $cached = 0)
    {
        $err = [];
        $checkData = [
            'project_id' => $projectId,
        ];
        $this->getProjectRuleSubScore();
        $decScore = 0;

        if ($cached > 0) {
            $res = Cache::get('project_warning_data:' . $projectId, null);
            if (!empty($res)) {
                return unserialize($res);
            }
        }

        foreach ($this->registeredProjectWarningRules as $registeredProjectWarningRule) {
            $result = $registeredProjectWarningRule->check($checkData);
            if ($result) {
                continue;
            }
            $err[$registeredProjectWarningRule->getCheckCode()] = $registeredProjectWarningRule->getErrorMessage();
            $decScore += count($err[$registeredProjectWarningRule->getCheckCode()]);
        }

        $score = 100 - ($decScore * $this->getProjectRuleSubScore());
        $res = ['score' => max($score, 0), 'err' => $err];
        if ($cached > 0) {
            Cache::set('project_warning_data:' . $projectId, serialize($res), $cached);
        }
        return $res;
    }
}
